package face.pay.profit.strategy;

import face.pay.constant.OrderType;
import face.pay.dao.*;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.IncomeInfo;
import face.pay.entity.OemInfo;
import face.pay.entity.OrderInfo;
import face.pay.profit.UserProfitBiz;
import face.pay.profit.core.RelationInfo;
import face.pay.profit.core.RelationType;
import face.pay.util.MathUtil;
import face.pay.vo.ProfitUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 默认策略 按等级 （级差） 和对应的 分佣比例（百分比）
 * 向上分三级
 */
@Component
@Slf4j
public class PercentageProfitStrategy extends  AbstractProfitStrategy {

    @Autowired
    OrderInfoDao orderInfoDao;

    @Autowired
    IncomeInfoDao incomeInfoDao;

    @Autowired
    EnterpriseInfoDao enterpriseInfoDao;


    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    UserProfitBiz userProfitBiz;

    @Autowired
    UserAccountDao userAccountDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void profit(OrderInfo orderInfo) throws  Exception {

        Integer userId = orderInfo.getUserId();

        Long orderId = orderInfo.getId();

        RelationInfo relationInfo =  userProfitBiz.getParUserRelation(userId);

        if(relationInfo!=null){

            log.info("成功获商家-代理商-层级关系");

            /**
             * 验证 opendId 绑定情况
             */
            OemInfo oemInfo =  relationInfo.getOemInfo();

            String appId = oemInfo.getAppId();

            String mchId = oemInfo.getMchId();

            List<IncomeInfo> incomeInfos = new ArrayList<>();

            Long actFee = orderInfo.getActFee();

            Integer enterprise_userId = orderInfo.getUserId();

            Integer oemId = orderInfo.getOemId();

            EnterpriseInfo enterpriseInfo = this.enterpriseInfoDao.queryByUserId(enterprise_userId);

            String  subMachId =enterpriseInfo.getWxSubMchId();

            /**
             * 商户自己
             */
            ProfitUser mch_user = relationInfo.get(RelationType.MCH_USER);


            Double rate = new Double(0);
            String orderType = orderInfo.getType();
            log.info("订单类型 "+orderType);
            if(OrderType.ALIPAY.equals(orderType)){

                rate =  enterpriseInfo.getAliFinalRate()==null?new Double(0):enterpriseInfo.getAliFinalRate();

            }else if(OrderType.WECHAT.equals(orderType)){
                rate =  enterpriseInfo.getWxFinalRate()==null?new Double(0):enterpriseInfo.getWxFinalRate();

            }
            log.info("商家费率 "+rate);

            if(rate>new Double("0.2") &&  rate<= new Double("0.6")){

                Long totalMoney =  Long.parseLong("0");

                Double enterprise_rate =   new BigDecimal(new Double(rate).toString()).divide(new BigDecimal("100")).doubleValue();


                Double totalRate =     addAgencyIncomeInfos(orderId,userId,actFee,totalMoney,enterprise_rate,incomeInfos,relationInfo);
                log.info("totalRate:"+totalRate);
                addOemIncomeInfo(orderId,userId, actFee, totalMoney,enterprise_rate,totalRate, incomeInfos,relationInfo);

                batchSaveIncome(incomeInfos);

                orderInfo.setProfitSign(1);

                this.orderInfoDao.updateProfitSign(orderInfo);
                /**
                 * 商家直接推荐代理商
                 */

            }else {
                log.error("商户 费率设置 限制 分佣终止");
            }

        }else {
            log.error("获取商户分佣层级关系失败,分佣终止");
        }
    }


    public Double addAgencyIncomeInfos(Long orderId,Integer mchUserId, Long totalFee,Long totalMoney,Double enterprise_rate,  List<IncomeInfo> incomeInfos,RelationInfo relationInfo) throws Exception {

        Double total_rate =   new BigDecimal(new Double(0.2).toString()).divide(new BigDecimal("100")).doubleValue();
        total_rate =  addAgencyIncomeInfo(orderId,mchUserId,totalFee,totalMoney,enterprise_rate,incomeInfos,relationInfo,RelationType.AGENCY_USER,total_rate);
        total_rate =  addAgencyIncomeInfo(orderId,mchUserId,totalFee,totalMoney,enterprise_rate,incomeInfos,relationInfo,RelationType.AGENCY_PERCENTAGE_USER_INDIRECT,total_rate);
        total_rate =  addAgencyIncomeInfo(orderId,mchUserId,totalFee,totalMoney,enterprise_rate,incomeInfos,relationInfo,RelationType.AGENCY_PERCENTAGE_USER_THIRD,total_rate);

        return total_rate;
    }

        /**
         *
         * @param orderId
         * @param totalFee
         * @param totalMoney
         * @param enterprise_rate
         * @param incomeInfos
         * @param relationInfo
         * @throws Exception
         */
    public Double addAgencyIncomeInfo(Long orderId,Integer mchUserId, Long totalFee,Long totalMoney,Double enterprise_rate,  List<IncomeInfo> incomeInfos,RelationInfo relationInfo,String key,Double total_rate) throws Exception {


        ProfitUser agencyProfitUser = relationInfo.get(key);

        if(agencyProfitUser!=null){
            log.info("记录收益 userId "+agencyProfitUser.getUserId());

            Double agencyProfit = new Double(0);

            if(RelationType.AGENCY_USER.equals(key)){
                agencyProfit = agencyProfitUser.getDirectConsumeProfit();
            }else   if(RelationType.AGENCY_PERCENTAGE_USER_INDIRECT.equals(key)){
                agencyProfit = agencyProfitUser.getIndirectConsumeProfit();
            }else   if(RelationType.AGENCY_PERCENTAGE_USER_THIRD.equals(key)){
                agencyProfit = agencyProfitUser.getThirdConsumeProfit();
            }


            total_rate = MathUtil.add(total_rate,agencyProfit);

            log.info(total_rate.toString());

            Double diff_rate = MathUtil.sub(enterprise_rate,total_rate);

            if(diff_rate.compareTo(new Double(0))==1){

                Long agency_consumeFee = MathUtil.profit(totalFee,agencyProfit);

                log.info("推荐分润金额： "+agency_consumeFee);
                if(agency_consumeFee.compareTo( new Long(0))==1){

                    IncomeInfo agencyIncomeInfo =  new IncomeInfo(agencyProfitUser.getUserId(),agencyProfitUser.getOemId(),agency_consumeFee,IncomeInfo.TYPE.CONSUME, orderId,totalFee);
                    agencyIncomeInfo.setSrcUserId(mchUserId);
                    if(new Integer(0).equals(agencyProfitUser.getDeleted())){
                        incomeInfos.add(agencyIncomeInfo);
                        totalMoney+=agency_consumeFee;
                    }else {
                        log.info("代理商户已注销");
                    }
                }
            }else{
                log.info("商家费率低于代理商分润 设置 分润终止");
                throw  new Exception("商家费率低于代理商分润 设置 分润终止");

            }
        }else {
            log.info("代理商"+key+"不存在");

        }
        return  total_rate;
    }

    private void addOemIncomeInfo(Long orderId,Integer mchUserId, Long totalFee,Long totalMoney,Double enterprise_rate,Double totalRate, List<IncomeInfo> incomeInfos, RelationInfo relationInfo) {

        ProfitUser oemUser = relationInfo.get(RelationType.OEM_USER);


        if(oemUser!=null){

            Double oemProfit = MathUtil.sub(enterprise_rate,totalRate);

            Long consumeFree = MathUtil.profit(totalFee,oemProfit);

            if(consumeFree.compareTo( new Long(0))==1){
                IncomeInfo recincomeInfo =  new IncomeInfo(oemUser.getUserId(),oemUser.getOemId(),consumeFree,IncomeInfo.TYPE.CONSUME, orderId,totalFee);
                recincomeInfo.setSrcUserId(mchUserId);
                incomeInfos.add(recincomeInfo);
            }
        }

    }

    private void batchSaveIncome(List<IncomeInfo> incomeInfos){

        for(IncomeInfo incomeInfo : incomeInfos){

            this.incomeInfoDao.insert(incomeInfo);

            userAccountDao.addMoney(incomeInfo.getOemId(),incomeInfo.getUserId(),incomeInfo.getMoney());

        }

    }

}
